home *** CD-ROM | disk | FTP | other *** search
- /*
- Commodore 64 Emulator v0.4 Earle F. Philhower III
- Copyright (C) 1993-4 (st916w9r@dunx1.ocs.drexel.edu)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include "Processor.h"
- #include "Error.h"
- #include "Resources.h"
- #include "Memory.h"
-
-
- /* Global memory pointers */
- byte *RAM=nil, *loROM=nil, *hiROM=nil, *charROM=nil;
- byte *RAMp1=nil, *loROMp1=nil, *hiROMp1=nil, *charROMp1=nil;
- byte **memory=nil, **memoryp1=nil;
-
- /* Used for the memory mapping routines locally */
- static byte **loRAMstore=nil, **loROMstore=nil;
- static byte **hiRAMstore=nil, **hiROMstore=nil;
- static byte **charRAMstore=nil, **charROMstore=nil;
-
-
- int MemoryInitialize(void)
- {
- Handle temp;
- word x;
-
- /* Get space for RAM and ROMS */
- RAM=(byte *)GetMemory(0x10001);
- loROM=(byte *)GetMemory(0x2000);
- charROM=(byte *)GetMemory(0x1000);
- hiROM=(byte *)GetMemory(0x2000);
- if ((RAM==nil)||(loROM==nil)||(charROM==nil)||(hiROM==nil))
- return(kOutOfMemory);
-
- /* Load the ROMS into the memory allocated */
- temp=GetResource('ROMS', kBASICROM); /* BASIC */
- if (temp==nil) return(kROMMissing);
- BlockMove(*temp, loROM, 0x2000);
- ReleaseResource(temp);
-
- temp=GetResource('ROMS', kCHARROM); /* CHARACTERS */
- if (temp==nil) return(kROMMissing);
- BlockMove(*temp, charROM, 0x1000);
- ReleaseResource(temp);
-
- temp=GetResource('ROMS', kKERNELROM); /* KERNAL */
- if (temp==nil) return(kROMMissing);
- BlockMove(*temp, hiROM, 0x2000);
- ReleaseResource(temp);
-
- /* Set up the hi-byte shortcut pointers */
- RAMp1=&RAM[1];
- loROMp1=&loROM[1];
- charROMp1=&charROM[1];
- hiROMp1=&hiROM[1];
-
- /* Get the double-dereference memory map space */
- memory=(byte**)GetMemory(0x10001*sizeof(byte *));
- if (memory!=nil) memoryp1=&(memory[1]);
- loRAMstore=(byte**)GetMemory(0x2000*sizeof(byte *));
- loROMstore=(byte**)GetMemory(0x2000*sizeof(byte *));
- charRAMstore=(byte**)GetMemory(0x1000*sizeof(byte *));
- charROMstore=(byte**)GetMemory(0x1000*sizeof(byte *));
- hiRAMstore=(byte**)GetMemory(0x2000*sizeof(byte *));
- hiROMstore=(byte**)GetMemory(0x2000*sizeof(byte *));
- if ((loRAMstore==nil)||(loROMstore==nil)||(charRAMstore==nil)||
- (charROMstore==nil)||(hiRAMstore==nil)||(hiROMstore==nil)||
- (memory==nil))
- return(kOutOfMemory);
-
- /* Set up the standard RAM pointers into our memory[] */
- for (x=0x0000; x<0xffff; x++) memory[x]=&RAM[x];
- memory[x]=&(RAM[x]); /* Takes care of overflow */
-
- /* Copy the ROM and RAM pointers into our holding places */
- for (x=0x0000; x<0x2000; x++) {
- loROMstore[x]=&loROM[x];
- loRAMstore[x]=&(RAM[0xa000+x]); }
- for (x=0x0000; x<0x1000; x++) {
- charROMstore[x]=&charROM[x];
- charRAMstore[x]=&(RAM[0xd000+x]); }
- for (x=0x0000; x<0x2000; x++) {
- hiROMstore[x]=&hiROM[x];
- hiRAMstore[x]=&(RAM[0xe000+x]); }
-
- return(kNoError);
- }
-
- void MemoryCleanUp(void)
- {
- if (RAM != nil) FreeMemory(RAM);
- if (loROM != nil) FreeMemory(loROM);
- if (charROM != nil) FreeMemory(charROM);
- if (hiROM != nil) FreeMemory(hiROM);
- if (memory != nil) FreeMemory(memory);
- if (loRAMstore != nil) FreeMemory(loRAMstore);
- if (loROMstore != nil) FreeMemory(loROMstore);
- if (charRAMstore != nil) FreeMemory(charRAMstore);
- if (charROMstore != nil) FreeMemory(charROMstore);
- if (hiRAMstore != nil) FreeMemory(hiRAMstore);
- if (hiROMstore != nil) FreeMemory(hiROMstore);
- }
-
- void SetUpMemoryMap(void)
- {
- if (*RAMp1&(1<<0)) BlockMove(loROMstore, &memory[0xa000],(0x2000*sizeof(byte *)));
- else BlockMove(loRAMstore, &memory[0xa000],(0x2000*sizeof(byte *)));
-
- if (*RAMp1&(1<<1)) BlockMove(charRAMstore, &memory[0xd000],(0x1000*sizeof(byte *)));
- else BlockMove(charROMstore, &memory[0xd000],(0x1000*sizeof(byte *)));
-
- if (*RAMp1&(1<<2)) BlockMove(hiROMstore, &memory[0xe000],(0x2000*sizeof(byte *)));
- else BlockMove(hiRAMstore, &memory[0xe000],(0x2000*sizeof(byte *)));
-
- CheckMemory();
- }
-
-
- #define SIGNATURE 'BoMb'
- #define MAXSLOTS 64
- typedef unsigned long SignatureType;
- typedef struct {
- byte *startOfMem, *givenMemPtr;
- SignatureType id;
- } Signature;
- static Signature signature[MAXSLOTS];
- static byte numSignatures=0;
-
- byte *GetMemory(unsigned long size)
- {
- byte *mem;
-
- /* First see if we've got room in our memory pointers */
- if (numSignatures==MAXSLOTS) InternalError(kOutOfMemoryPointers);
-
- /* Get memory from heap, including space for our signature */
- mem=(byte *)NewPtrClear(size+sizeof(SignatureType));
- if (mem==nil) return (byte *)nil;
-
- /* Set up our memory structure */
- signature[numSignatures].startOfMem=mem;
- signature[numSignatures].givenMemPtr=&(mem[sizeof(SignatureType)]);
- signature[numSignatures].id=SIGNATURE;
-
- /* Store out "sentinel" bytes that SHOULD NOT BE OVERWRITTEN */
- BlockMove(&(signature[numSignatures].id), mem, sizeof(SignatureType));
-
- /* Return address just after out sentinel */
- return signature[numSignatures++].givenMemPtr;
- }
-
- void FreeMemory(void *mem)
- {
- int x, y;
- byte *memory=(byte *)mem;
-
- /* Search for the passed memory pointer in the list of ones we've given */
- for (x=0; x<numSignatures; x++)
- if (memory==signature[x].givenMemPtr)
- {
- /* Found a match, free the memory */
- DisposePtr((Ptr)signature[x].startOfMem);
- /* Shift out pointers down to fill the vacant slot */
- for (y=x; y<numSignatures; y++) signature[y]=signature[y+1];
- numSignatures--;
- return;
- }
- /* Didn't find the memory, so exit gracefully */
- InternalError(kInvalidMemoryFree);
- }
-
- void CheckMemory(void)
- {
- int x;
- SignatureType sign;
-
- /* Scan all of out given signatures for the sentinel value */
- for (x=0; x<numSignatures; x++)
- {
- sign=*(SignatureType *)signature[x].startOfMem;
- if (sign!=signature[x].id) InternalError(kMemoryViolation);
- }
- }
-